import os, pygame, math
from pygame.locals import *
import random

class CardGroup:

    def __init__(self, cards=[]):
        self.m_cards = cards

    def shuffle(self):
        rectbuf = []
        for c in self.m_cards:
            rectbuf.append(pygame.Rect(c.rect))

        random.shuffle(self.m_cards)

        for i in range(len(rectbuf)):
            self.m_cards[i].rect = rectbuf[i]

    def collectAll(self, x, y):
        """Pile all the cards to position """
        for c in self.m_cards:
            c.rect.x = x;
            c.rect.y = y;
            c.backSide();
            c.selected = 0
            c.parent = None
            c.child = None

    def getCardAt(self, idx):
        fc = self.m_cards.pop(idx)
        self.m_cards.append(fc)
        return fc

    def getCardById(self, id):
        for card in self.m_cards:
            if card.id == id:
                idx = self.m_cards.index(card)
                return self.getCardAt(idx)
        return None

    def popCards(self, cards):
        for c in cards:
            #pop card
            self.m_cards.remove(c)
            self.m_cards.append(c)

    def getCards(self, rect):
        r = None
        selCards = []
        for c in self.m_cards:
            if rect.contains(c.rect):
                c.selected = 1
                selCards.append(c)

                # disconnect card
                if c.parent:
                    c.parent.child = None

                if c.child:
                    c.child.parent = None
                    self.dropCard(c.child)

                c.child = None
                c.parent = None

                # add to rectangle                    
                if not r:
                    r = pygame.Rect(c.rect)
                else:
                    r.union_ip(c.rect)
        if r:
            r.x -= 3
            r.y -= 3
            r.width += 6
            r.height += 6

            self.popCards(selCards)

            return(r, selCards)
        else:
            rect.size = (0, 0)
            return(rect, [])

    def getCard(self, x, y, popsingle=0):
        for i in range(len(self.m_cards) - 1, -1, -1):
            if self.m_cards[i].rect.collidepoint(x, y):
                fc = self.m_cards.pop(i)
                self.m_cards.append(fc)
                if fc.parent:
                    fc.parent.child = None
                    fc.parent = None

                if popsingle:
                    if fc.child:
                        fc.child.parent = None
                        self.dropCard(fc.child)
                        fc.child = None
                else:
                    c = fc.child
                    while c:
                        self.m_cards.remove(c)
                        self.m_cards.append(c)
                        c = c.child
                return fc

        return None

    def getCardWithoutTossing(self, x, y):
        for i in range(len(self.m_cards) - 1, -1, -1):
            if self.m_cards[i].rect.collidepoint(x, y):
                fc = self.m_cards[i]
                return fc

        return None

    def highlightOff(self):
        for i in range(len(self.m_cards) - 1, -1, -1):
            self.m_cards[i].setHighlight(False)

    def dropCard(self, card):
        idx = self.m_cards.index(card)
        for i in range(idx - 1, -1, -1):
            if not self.m_cards[i].child and not self.m_cards[i].selected:
                if self.m_cards[i].rect.colliderect(card.rect):
                    self.m_cards[i].child = card
                    card.parent = self.m_cards[i]
                    return

    def dropCards(self, cards):
        for c in cards:
            c.selected = 0
            c.child = None
            c.parent = None
            self.dropCard(c)

    def draw(self, surface):
        for c in self.m_cards:
            c.draw(surface)

    def setCards(self, cards=[]):
        self.m_cards = cards

    def addCard(self, card):
        self.m_cards.append(card)


class CardGroupGL(CardGroup):
    def draw(self):
        for c in self.m_cards:
            c.draw()
